/*
===========================================================================
Copyright (C) 2013-2014 Avotu Briezhaudzetava
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.

===========================================================================
*/

//
// log.cpp (main.cpp is too crowded)
//

//
// includes
//
#include "main.h"
#include <QSqlQuery>
#include <QSqlError>

/*
================
logForId
================
*/
LogEntry *Main::logForId( int id ) const {
    foreach ( LogEntry *lPtr, this->logList ) {
        if ( lPtr->id() == id )
            return lPtr;
    }
    return NULL;
}

/*
================
filterLogs
================
*/
void Main::filterLogs( int precursorId ) {
    this->logListFiltered.clear();
    foreach ( LogEntry *lPtr, this->logList ) {
        if ( lPtr->precursorId() == precursorId )
            this->logListFiltered << lPtr;
    }
}

/*
================
addLog
================
*/
void Main::addLog( int precursorId, int userId, float amount, const QString &date, const QString &purpose, Common::Units units ) {
    QSqlQuery query;

    // failsafe
    if ( precursorId == -1 || static_cast<int>( units ) == -1 ) {
        m.error( StrSoftError + QString( "invalid units '%1'\n" ).arg( static_cast<int>( units )));
        return;
    }

    // perform database update and select last row
    if ( !query.exec( QString( "insert into logs values ( null, '%1', %2, '%3', '%4', '%5', '%6' )" )
                      .arg( precursorId )                   // 1
                      .arg( userId )                        // 2
                      .arg( amount )                        // 3
                      .arg( date )                          // 4
                      .arg( purpose )                       // 5
                      .arg( units )                         // 6
                      )) {
        this->error( StrSoftError + QString( "could not add log, reason: \"%1\"\n" ).arg( query.lastError().text()));
    }
    query.exec( QString( "select * from logs where id=%1" ).arg( query.lastInsertId().toInt()));

    // get last entry and construct internal entry
    while ( query.next())
        this->logList << new LogEntry( query.record(), "precursors" );

   // refresh logs
   emit this->logListChanged();
}

/*
================
removeLog
================
*/
void Main::removeLog( int id ) {
    LogEntry *lPtr = NULL;
    QSqlQuery query;

    // find log
    lPtr = this->logForId( id );

    // failsafe
    if ( lPtr == NULL )
        return;

    // remove log from db
    query.exec( QString( "delete from logs where id=%1" ).arg( lPtr->id()));

    // remove from display
    this->logList.removeAll( lPtr );

    // refresh logs
    emit this->logListChanged();
}

/*
================
loadLogs
================
*/
void Main::loadLogs() {
    QSqlQuery query;

    // read stuff
    query.exec( "select * from logs" );

    // store entries
    while ( query.next())
        this->logList << new LogEntry( query.record(), "logs" );

    // refresh logs
    emit this->logListChanged();
}

/*
================
remaining
================
*/
float Main::remaining( int logId ) const {
    LogEntry *lPtr = NULL;
    const PrecursorEntry *pPtr;
    float amount;

    // find log
    lPtr = this->logForId( logId );

    // failsafe
    if ( lPtr == NULL )
        return 0.0;

    // find solvent
    pPtr = this->precursorForId( lPtr->precursorId());

    // failsafe
    if ( pPtr == NULL )
        return 0.0;

    // calculate
    amount = pPtr->baseAmount();
    foreach ( LogEntry *lPtrList, this->logListFiltered ) {
        amount += lPtrList->amountTo( pPtr->units(), pPtr->density());
        if ( lPtrList == lPtr )
            break;
    }
    return amount;
}
